home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
v7n13.arc
/
QFN.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-06-06
|
9KB
|
251 lines
name qfn
title QFN.ASM --- qualify file name
page 55,132
;
;
; QFN.ASM -- Qualify File Name
;
; Copyright (C) 1988 Ziff Davis
; by Ray Duncan Feb. 1988
;
; Call with: DS:SI = filename address
; AX = length
;
; Returns: Carry = clear if filename OK
; DS:SI = qualified filename
; AX = length
; or
; Carry = set if bad filename
;
; Registers other than DS:SI
; and AX are preserved.
;
DGROUP group _DATA
_DATA segment word public 'DATA'
cdrive db 0 ; current drive
cpath db '\',64 dup (0) ; current directory
tbuff db 64 dup (0) ; target directory
qbuff db 'X:\' ; qualified pathname
db 64 dup (0)
fname dw ? ; filename address
flen dw ? ; filename length
_DATA ends
_TEXT segment word public 'CODE'
assume cs:_TEXT,ds:DGROUP
public qfn ; make visible to Linker
qfn proc near ; qualify file name
push bx ; save registers
push cx
push dx
push di
push es
mov flen,ax ; save length and
mov fname,si ; address of filename
mov ax,ds ; make DGROUP addressable
mov es,ax ; with ES register
; save current drive...
mov ah,19h ; fxn 19h = get drive
int 21h ; transfer to MS-DOS
mov cdrive,al ; save it
; save current directory...
; DS:SI = buffer
mov si,offset DGROUP:cpath+1
mov ah,47h ; fxn 47h = get directory
mov dl,0 ; drive = current
int 21h ; transfer to MS-DOS
; did caller specify drive?
mov di,fname ; get address of name
mov cx,flen ; get length of name
cmp cx,2 ; if drive, length must
; be >= 2 chars.
jl qfn2 ; too short, no drive
; check for drive delimiter
cmp byte ptr [di+1],':'
jne qfn2 ; no delimiter, jump
mov dl,[di] ; get ASCII drive code
or dl,20h ; fold to lower case
sub dl,'a' ; convert it to binary
mov ah,0eh ; fxn 0eh = select drive
int 21h ; transfer to MS-DOS
; get current drive to
; make sure drive selected
mov ah,19h ; fxn 19h = get current drive
int 21h ; transfer to MS-DOS
cmp dl,al ; current = requested?
je qfn1 ; jump if select succeeded
jmp qfn8 ; exit, select failed
qfn1: add di,2 ; bump pointer past drive
sub cx,2 ; and decrement length
qfn2: ; save current directory
; again for new drive...
; DS:SI = buffer
mov si,offset DGROUP:cpath+1
mov ah,47h ; fxn 47h = get directory
mov dl,0 ; drive = current
int 21h ; transfer to MS-DOS
; scan off path if any
push di ; save start of path
mov al,'\' ; path delimiter
qfn3: mov fname,di ; save path pointer
mov flen,cx ; save path length
jcxz qfn4 ; jump if none left
repne scasb ; any '\' left in path?
je qfn3 ; loop if '\' found
qfn4: pop si ; recover starting address
; of path portion
; copy path to local buffer
; and make it ASCIIZ...
mov di,offset DGROUP:tbuff
mov cx,fname ; calculate path length
sub cx,si
jz qfn6 ; jump, no path at all
cmp cx,1 ; root directory?
je qfn5 ; jump if root
dec cx ; else discard last '\'
qfn5: rep movsb ; transfer path and
xor al,al ; append null byte
stosb
; now make target directory
; the current directory...
mov dx,offset DGROUP:tbuff
mov ah,3bh ; fxn 3BH = select directory
int 21h ; transfer to MS-DOS
jc qfn8 ; jump, no such directory
qfn6: ; build up full pathname...
mov ah,19h ; get current drive
int 21h ; transfer to MS-DOS
add al,'A' ; convert binary to ASCII
mov qbuff,al ; store ASCII drive code
; get current directory
mov dl,0 ; DL = 0 for default drive
; DS:SI = buffer address
mov si,offset DGROUP:qbuff+3
mov ah,47h ; fxn 47h = get current dir
int 21h ; transfer to MS-DOS
jc qfn8 ; jump if error
; point to path component
mov di,offset DGROUP:qbuff+3
cmp byte ptr [di],0 ; is current directory
; the root directory?
je qfn7 ; yes, jump
xor al,al ; scan for null byte at
mov cx,-1 ; end of path name
repne scasb ; and append backslash
mov byte ptr [di-1],'\'
qfn7: ; now append filename
; to drive and path...
mov si,fname ; filename address
cmp byte ptr [si],'.'
je qfn8 ; exit if directory alias
mov cx,flen ; filename length
rep movsb ; copy it
; set DS:SI = address
mov si,offset DGROUP:qbuff
mov ax,di ; and AX = length of
sub ax,si ; fully qualified filename
call makelc ; fold filename to lower
; case to make it pretty
clc ; Carry = false to
; indicate success
jmp qfn9 ; jump to common exit
qfn8: ; come here if any
; error detected...
stc ; Carry = true to
; indicate error
qfn9: pushf ; save Carry flag
push ax ; save final length
; restore original directory
mov dx,offset DGROUP:cpath
mov ah,3bh ; fxn 3BH = select directory
int 21h ; transfer to MS-DOS
mov dl,cdrive ; restore original drive
mov ah,0eh ; fxn 0EH = set drive
int 21h ; transfer to MS-DOS
pop ax ; restore length
popf ; and Carry flag
pop es ; restore other affected
pop di ; registers
pop dx
pop cx
pop bx
ret ; back to caller
qfn endp
makelc proc near ; string -> lower case
; DS:SI = address
; AX = length
push bx ; save BX contents
xor bx,bx ; BX will be pointer
mlc1: ; change A-Z to a-z
cmp byte ptr [bx+si],'A'
jb mlc2
cmp byte ptr [bx+si],'Z'
ja mlc2
or byte ptr [bx+si],20h
mlc2: inc bx ; advance through string
cmp bx,ax ; done with string yet?
jne mlc1 ; no, check next char.
pop bx ; restore BX and
ret ; return to caller
makelc endp
_TEXT ends
end